
    <!DOCTYPE html>
    <html lang="zh-CN">
    <head>
      <meta charset="UTF-8">
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
      <title>Chat Prompt - 交互式测验</title>
      <style>
        @import url('https://fonts.googleapis.com/css2?family=Noto+Sans+SC:wght@400;500;700&display=swap');
        
        body {
          font-family: 'Noto Sans SC', sans-serif;
          background-color: #f4f7f9;
          color: #333;
          display: flex;
          justify-content: center;
          align-items: center;
          min-height: 100vh;
          margin: 0;
          padding: 20px;
          box-sizing: border-box;
        }
        
        .main-wrapper {
            position: relative;
            width: 100%;
            max-width: 900px; /* Wider to accommodate buttons */
            display: flex;
            justify-content: center;
            align-items: center;
        }

        .quiz-container {
          background-color: #ffffff;
          border-radius: 16px;
          box-shadow: 0 8px 32px rgba(0, 0, 0, 0.1);
          width: 100%;
          max-width: 700px;
          overflow: hidden;
          z-index: 10;
        }

        .quiz-header {
          background-color: #4a90e2;
          color: white;
          padding: 20px 30px;
          text-align: center;
        }

        .quiz-header h1 {
          margin: 0;
          font-size: 24px;
          font-weight: 700;
        }
        
        .quiz-header p {
            margin: 5px 0 0;
            font-size: 14px;
            opacity: 0.9;
        }

        .quiz-body {
          padding: 30px;
        }

        .progress-bar {
            display: none; /* 隐藏进度条 */
            width: 100%;
            background-color: #e0e0e0;
            border-radius: 5px;
            height: 10px;
            margin-bottom: 20px;
        }

        #progress-indicator {
            height: 100%;
            width: 0%;
            background-color: #4caf50;
            border-radius: 5px;
            transition: width 0.3s ease;
        }

        #question-container {
          margin-bottom: 20px;
        }

        #question-text {
          font-size: 18px;
          font-weight: 500;
          line-height: 1.6;
          margin-bottom: 25px;
        }

        .options-list {
          list-style: none;
          padding: 0;
          margin: 0;
        }

        .option-item {
          background-color: #f8f9fa;
          border: 1px solid #dee2e6;
          border-radius: 8px;
          padding: 15px;
          margin-bottom: 12px;
          cursor: pointer;
          transition: background-color 0.2s ease, border-color 0.2s ease;
        }

        .option-item:hover {
          background-color: #e9ecef;
        }
        
        .option-item.selected {
            background-color: #d1e7fd;
            border-color: #4a90e2;
        }

        .quiz-footer {
          padding: 20px 30px;
          display: flex;
          justify-content: space-between; /* 将按钮分布在两侧 */
          align-items: center;
          min-height: 65px; /* Reserve space */
        }

        .nav-btn {
          background-color: #4a90e2;
          color: white;
          border: none;
          border-radius: 8px;
          padding: 10px 20px;
          font-size: 16px;
          font-weight: 500;
          cursor: pointer;
          transition: background-color 0.2s ease, transform 0.2s ease;
          box-shadow: 0 4px 12px rgba(0,0,0,0.15);
        }
        
        #next-btn {
            background-color: #28a745;
        }

        .nav-btn:hover {
          background-color: #357abd;
          transform: scale(1.05);
        }
        
        .nav-btn:disabled {
            background-color: #a0c3e8;
            cursor: not-allowed;
            opacity: 0.7;
        }

        #result-container {
            border-top: 1px solid #eee;
        }
        
        .result-box {
            border-radius: 8px;
            padding: 20px;
            margin-top: 20px;
        }
        
        .result-box.correct {
            background-color: #d4edda;
            border: 1px solid #c3e6cb;
            color: #155724;
        }

        .result-box.incorrect {
            background-color: #f8d7da;
            border: 1px solid #f5c6cb;
            color: #721c24;
        }
        
        .result-box h3 {
            margin-top: 0;
        }

        .explanation-text {
            margin-top: 15px;
            line-height: 1.7;
        }
        
        .source-text {
            font-style: italic;
            font-size: 14px;
            margin-top: 15px;
            color: #555;
        }

        
        .final-score-container {
            padding: 40px;
            text-align: center;
        }
        .final-score-container h2 {
            margin-top: 0;
            margin-bottom: 30px;
        }
        .score-summary {
            display: flex;
            justify-content: center;
            gap: 20px;
            margin-bottom: 40px;
            flex-wrap: wrap;
        }
        .score-card {
            background-color: #f8f9fa;
            border-radius: 12px;
            padding: 20px;
            width: 180px;
            box-shadow: 0 4px 12px rgba(0,0,0,0.05);
            border: 1px solid #e9ecef;
        }
        .score-card h3 {
            margin: 0 0 10px;
            font-size: 16px;
            font-weight: 500;
            color: #555;
        }
        .score-card p {
            margin: 0;
            font-size: 28px;
            font-weight: 700;
            color: #333;
        }
        .score-details table {
            width: 100%;
            font-size: 16px;
        }
        .score-details td {
            padding: 4px 0;
        }
        .score-details td:last-child {
            text-align: right;
            font-weight: 700;
        }
        .report-actions button {
            background-color: #fff;
            border: 1px solid #ccc;
            border-radius: 8px;
            padding: 12px 25px;
            font-size: 16px;
            cursor: pointer;
            margin: 0 10px;
            transition: background-color 0.2s ease, border-color 0.2s ease, transform 0.2s ease;
        }
        .report-actions button:hover {
            background-color: #f1f1f1;
            border-color: #bbb;
            transform: translateY(-2px);
        }
        .report-actions button.primary {
            background-color: #28a745;
            color: white;
            border-color: #28a745;
        }
        .report-actions button.primary:hover {
            background-color: #218838;
        }
        
        .hint-container {
            background-color: #e0f7fa;
            border: 1px solid #b2ebf2;
            border-radius: 8px;
            padding: 15px;
            margin-top: 20px;
            color: #006064;
            font-size: 15px;
            line-height: 1.6;
            display: none; /* 默认隐藏 */
        }
      </style>
    </head>
    <body>
      <div class="main-wrapper">
          <div class="quiz-container">
            <div class="quiz-header">
              <h1>Chat Prompt - 交互式测验</h1>
              <p>检验你对文档内容的理解程度</p>
            </div>
            <div id="quiz-content">
                <div class="quiz-body">
                    <div class="progress-bar">
                        <div id="progress-indicator"></div>
                    </div>
                    <div id="question-container">
                      <p id="question-text"></p>
                      <ul class="options-list" id="options-list"></ul>
                    </div>
                    <div id="result-container"></div>
                    <div id="hint-container" class="hint-container"></div>
                </div>
                <div class="quiz-footer" id="quiz-footer">
                  <button id="prev-btn" class="nav-btn">上一题</button>
                  <button id="hint-btn" class="nav-btn" style="background-color: #ffc107; color: #333; box-shadow: 0 4px 12px rgba(255,193,7,0.3);">提示</button>
                  <button id="next-btn" class="nav-btn">下一题</button>
                </div>
            </div>
          </div>
      </div>

      <script>
        const quizData = [
  {
    "question": "在分布式系统的CAP理论中，为什么'P' (分区容错性) 通常被认为是必须保证的？",
    "options": [
      "因为分区容错性可以显著提升系统的单点性能。",
      "因为网络分区（如节点间通信中断）在分布式环境中是不可避免的，系统必须能够在这种情况下继续运行。",
      "因为保证了分区容错性后，系统可以同时实现100%的一致性(C)和可用性(A)。",
      "因为'P'代表持久性(Persistence)，是保证数据不丢失的基础。"
    ],
    "correctAnswerIndex": 1,
    "explanation": "CAP理论指出，任何分布式系统最多只能同时满足一致性（C）、可用性（A）和分区容错性（P）中的两项。在分布式系统中，网络延迟、中断等问题是常态，这意味着分区是必然会发生的。因此，分区容错性（P）成为了设计分布式系统时必须保障的基础，我们通常需要在一致性（C）和可用性（A）之间进行权衡。",
    "source": "文档中「核心理论：CAP与BASE」部分",
    "hint": "想一想在由多台机器组成的网络中，最常见且不可控的问题是什么？"
  },
  {
    "question": "两阶段提交 (2PC) 协议最主要的缺点是什么？",
    "options": [
      "它是一个同步阻塞协议，如果协调者在第二阶段宕机，所有参与者都会被锁定资源，等待协调者恢复。",
      "它无法保证事务的原子性，可能导致部分节点提交、部分节点回滚。",
      "它的实现过于简单，无法处理复杂的跨数据库事务。",
      "它在第一阶段（准备阶段）消耗过多的网络带宽。"
    ],
    "correctAnswerIndex": 0,
    "explanation": "2PC的最大问题在于其同步阻塞机制。当协调者向所有参与者发送commit请求后，如果协调者自身发生故障，那么已经锁定资源的参与者将无法收到最终指令（是提交还是回滚），导致资源一直被占用，从而严重影响系统的可用性。",
    "source": "文档中「刚性事务解决方案：两阶段提交 (2PC)」部分",
    "hint": "如果事务的“总指挥”（协调者）在下达最终命令前突然失联，那么“士兵们”（参与者）会处于什么状态？"
  },
  {
    "question": "以下哪一项最准确地描述了BASE理论的核心思想？",
    "options": [
      "强一致性 (Strongly Consistent), 原子性 (Atomic), 隔离性 (Isolated)",
      "基本可用 (Basically Available), 软状态 (Soft state), 最终一致性 (Eventually consistent)",
      "全局有序 (Globally Ordered), 可串行化 (Serializable), 持久化 (Durable)",
      "始终可用 (Always Available), 硬状态 (Hard state), 立即一致性 (Immediately consistent)"
    ],
    "correctAnswerIndex": 1,
    "explanation": "BASE理论是CAP理论在实践中的延伸，它面向的是大型高可用分布式系统。其核心思想是，即使无法做到强一致性（ACID中的C），但系统可以通过牺牲一定的一致性来获得更好的可用性和扩展性，并让数据在一段时间后达到最终一致。这三个特性分别是：基本可用、软状态（状态允许在一段时间内不同步）、最终一致性。",
    "source": "文档中「核心理论：CAP与BASE」部分",
    "hint": "BASE理论通常被看作是传统数据库ACID模型的反面，它更强调系统的可用性而非强一致性。"
  },
  {
    "question": "与2PC相比，三阶段提交 (3PC) 协议引入了什么关键机制来减少阻塞风险？",
    "options": [
      "移除了协调者角色，使所有参与者对等通信。",
      "引入了一个“预提交”(CanCommit)阶段和超时机制。",
      "强制要求所有参与者必须在同一个数据中心。",
      "将所有操作日志都先写入一个中心化的持久存储。"
    ],
    "correctAnswerIndex": 1,
    "explanation": "3PC在2PC的“准备阶段”和“提交阶段”之间，增加了一个“预提交”阶段。同时，在协调者和参与者中都引入了超时机制。通过这个额外的阶段和超时机制，3PC降低了在协调者或参与者单点故障时，系统陷入无限期阻塞的概率，提升了系统的容错能力。",
    "source": "文档中「2PC的改进：三阶段提交 (3PC)」部分",
    "hint": "思考一下，在做出一个不可逆的决定之前，增加一个“意向确认”环节会有什么好处？"
  },
  {
    "question": "在TCC (Try-Confirm-Cancel) 模式中，'Cancel'操作的用途是什么？",
    "options": [
      "在 'Try' 阶段成功后，正式确认并提交业务操作。",
      "当任何一个服务的 'Try' 操作失败或最终需要回滚事务时，执行预定义的补偿逻辑来撤销'Try'阶段的影响。",
      "用于取消用户的请求，并立即释放所有系统资源。",
      "记录事务失败的详细日志，供开发人员进行手动恢复。"
    ],
    "correctAnswerIndex": 1,
    "explanation": "TCC是一种补偿型事务模型。'Try'阶段负责检查和预留业务资源；'Confirm'阶段在所有参与方'Try'成功后，执行真正的业务提交；而'Cancel'阶段则是在'Try'阶段有任何一方失败，或协调方决定回滚时，调用对应服务的补偿接口，释放预留的资源，从而达到回滚的效果。",
    "source": "文档中「柔性事务解决方案：TCC模式」部分",
    "hint": "当你在网上预订机票和酒店，支付环节失败了，系统应该如何自动取消你之前已经占用的机票和酒店房间？"
  },
  {
    "question": "Saga模式是如何实现分布式事务的数据一致性的？",
    "options": [
      "通过全局锁来锁定所有相关数据，在事务结束后统一释放。",
      "它将一个长事务分解为一系列独立的本地事务，并为每个事务提供一个对应的补偿事务，在发生错误时反向执行补偿事务来回滚。",
      "它要求所有参与的微服务共享同一个数据库实例。",
      "通过一个强大的中央协调器实时监控并保证所有节点数据强一致性。"
    ],
    "correctAnswerIndex": 1,
    "explanation": "Saga模式的核心思想是将一个大的全局事务拆分成多个有序的、独立的本地事务。每个本地事务完成自己的操作并提交。如果整个Saga流程中的任何一步失败了，系统会按相反的顺序依次调用之前已经成功执行的本地事务的“补偿事务”，从而使得数据状态在逻辑上恢复到事务开始前的状态，达到最终一致性。",
    "source": "文档中「柔性事务解决方案：Saga模式」部分",
    "hint": "这个模式类似于一个“撤销”操作链，每走一步，都要准备好如何“退回”这一步。"
  }
];
        console.log("Quiz Data:", JSON.parse(JSON.stringify(quizData))); // 添加这行用于调试，以可展开的JSON格式输出
        
        let currentQuestionIndex = 0;
        let score = 0;
        // 存储每个问题的回答状态
        const userAnswers = new Array(quizData.length).fill(null); 

        const questionTextEl = document.getElementById('question-text');
        const optionsListEl = document.getElementById('options-list');
        const resultContainerEl = document.getElementById('result-container');
        const quizContentEl = document.getElementById('quiz-content');
        const progressIndicatorEl = document.getElementById('progress-indicator');
        const prevBtn = document.getElementById('prev-btn');
        const nextBtn = document.getElementById('next-btn');
        const hintBtn = document.getElementById('hint-btn');
        const hintContainerEl = document.getElementById('hint-container');

        function loadQuestion() {
          resultContainerEl.innerHTML = '';
          optionsListEl.innerHTML = '';
          hintContainerEl.style.display = 'none'; // 隐藏提示
          
          if (currentQuestionIndex >= quizData.length) {
            showFinalScore();
            return;
          }

          updateProgress();

          const currentQuestion = quizData[currentQuestionIndex];
          questionTextEl.textContent = `(${currentQuestionIndex + 1}/${quizData.length}) ${currentQuestion.question}`;
          
          currentQuestion.options.forEach((optionText, index) => {
            const li = document.createElement('li');
            li.className = 'option-item';
            li.textContent = optionText;
            li.dataset.index = index; // Store index in a data attribute
            // 如果这道题已经回答过，恢复状态
            if (userAnswers[currentQuestionIndex] !== null) {
                if (index === userAnswers[currentQuestionIndex]) {
                    li.classList.add('selected');
                }
            }
            optionsListEl.appendChild(li);
          });

          // 如果已经回答过，直接显示结果
          if (userAnswers[currentQuestionIndex] !== null) {
              const isCorrect = userAnswers[currentQuestionIndex] === currentQuestion.correctAnswerIndex;
              showResult(isCorrect, currentQuestion);
          }
          
          updateNavigationButtons();
          updateProgress();
        }

        function selectOption(optionIndex) {
            userAnswers[currentQuestionIndex] = optionIndex;
            const currentQuestion = quizData[currentQuestionIndex];
            const isCorrect = optionIndex === currentQuestion.correctAnswerIndex;

            // 重新计算分数
            score = userAnswers.reduce((acc, answer, index) => {
                return answer === quizData[index].correctAnswerIndex ? acc + 1 : acc;
            }, 0);

            showResult(isCorrect, currentQuestion);
            updateNavigationButtons();
        }
        
        function updateProgress() {
            const answeredQuestions = userAnswers.filter(answer => answer !== null).length;
            const progressPercentage = (answeredQuestions / quizData.length) * 100;
            progressIndicatorEl.style.width = `${progressPercentage}%`;
        }
        
        function updateNavigationButtons() {
            prevBtn.style.display = 'block';
            nextBtn.style.display = 'block';
            hintBtn.style.display = 'block'; // 显示提示按钮

            prevBtn.disabled = currentQuestionIndex === 0;
            nextBtn.disabled = false; // 最后一题时，下一题按钮不禁用，而是用于显示报告
            nextBtn.textContent = (currentQuestionIndex === quizData.length - 1) ? '查看报告' : '下一题';
            
            // 如果当前问题没有提示，则禁用提示按钮并隐藏提示内容
            if (!quizData[currentQuestionIndex].hint) {
                hintBtn.disabled = true;
                hintContainerEl.style.display = 'none';
                hintContainerEl.textContent = ''; // 清除旧的提示内容
            } else {
                hintBtn.disabled = false;
            }
        }

        function showResult(isCorrect, questionData) {
            resultContainerEl.innerHTML = ''; // 清空之前的结果
            const resultBox = document.createElement('div');
            resultBox.className = `result-box ${isCorrect ? 'correct' : 'incorrect'}`;
            
            let html = `<h3>${isCorrect ? '回答正确！' : '回答错误'}</h3>`;
            if (!isCorrect) {
                html += `<p><strong>正确答案是：</strong> ${questionData.options[questionData.correctAnswerIndex]}</p>`;
            }
            html += `<div class="explanation-text">${questionData.explanation}</div>`;
            html += `<div class="source-text">来源: ${questionData.source}</div>`;
            
            resultBox.innerHTML = html;
            resultContainerEl.appendChild(resultBox);

            // 禁用所有选项的点击事件，并高亮正确/错误答案
            Array.from(optionsListEl.children).forEach((child, index) => {
                child.style.pointerEvents = 'none';
                // 高亮正确答案
                if (index === questionData.correctAnswerIndex) {
                    child.classList.add('correct'); // 需要添加CSS样式
                    child.style.backgroundColor = '#d4edda';
                    child.style.borderColor = '#c3e6cb';
                }
                // 如果选错了，高亮错误选项
                if (!isCorrect && index === userAnswers[currentQuestionIndex]) {
                    child.classList.add('incorrect'); // 需要添加CSS样式
                    child.style.backgroundColor = '#f8d7da';
                    child.style.borderColor = '#f5c6cb';
                }
            });
        }

        function goToNextQuestion() {
            if (currentQuestionIndex < quizData.length - 1) {
                currentQuestionIndex++;
                loadQuestion();
            } else {
                showFinalScore();
            }
        }

        function goToPreviousQuestion() {
            if (currentQuestionIndex > 0) {
                currentQuestionIndex--;
                loadQuestion();
            }
        }
        
        function showHint() {
            const currentQuestion = quizData[currentQuestionIndex];
            if (currentQuestion.hint) {
                hintContainerEl.textContent = currentQuestion.hint;
                hintContainerEl.style.display = 'block';
            } else {
                hintContainerEl.style.display = 'none';
            }
        }

        function showFinalScore() {
            document.querySelector('.quiz-body').style.display = 'none';
            document.getElementById('quiz-footer').style.display = 'none';

            const correctCount = score;
            const totalQuestions = quizData.length;
            const answeredCount = userAnswers.filter(a => a !== null).length;
            const wrongCount = answeredCount - correctCount;
            const skippedCount = totalQuestions - answeredCount;
            const accuracy = totalQuestions > 0 ? Math.round((correctCount / totalQuestions) * 100) : 0;
            const errorRate = totalQuestions > 0 ? Math.round((wrongCount / totalQuestions) * 100) : 0;

            const finalScoreHtml =
                '<div class="final-score-container">' +
                '<h2>答题报告</h2>' +
                '<div class="score-summary">' +
                '<div class="score-card">' +
                '<h3>得分</h3>' +
                '<p>' + correctCount + ' / ' + totalQuestions + '</p>' +
                '</div>' +
                '<div class="score-card">' +
                '<h3>正确率</h3>' +
                '<p>' + accuracy + '%</p>' +
                '</div>' +
                '<div class="score-card">' +
                '<h3>错误率</h3>' +
                '<p>' + errorRate + '%</p>' +
                '</div>' +
                '<div class="score-card score-details">' +
                '<table>' +
                '<tr><td>正确</td><td>' + correctCount + '</td></tr>' +
                '<tr><td>错误</td><td>' + wrongCount + '</td></tr>' +
                '<tr><td>未答</td><td>' + skippedCount + '</td></tr>' +
                '</table>' +
                '</div>' +
                '</div>' +
                '<div class="report-actions">' +
                '<button id="review-btn">回顾测验</button>' +
                '<button class="primary" onclick="location.reload()">再试一次</button>' +
                '</div>' +
                '</div>';

            let reportEl = document.querySelector('.final-score-container');
            if (reportEl) {
                reportEl.remove();
            }
            quizContentEl.insertAdjacentHTML('beforeend', finalScoreHtml);
            document.getElementById('review-btn').addEventListener('click', reviewQuiz);
        }

        function reviewQuiz() {
            const reportEl = document.querySelector('.final-score-container');
            if (reportEl) {
                reportEl.remove();
            }

            document.querySelector('.quiz-body').style.display = 'block';
            document.getElementById('quiz-footer').style.display = 'flex';
            
            currentQuestionIndex = 0;
            loadQuestion();
            updateNavigationButtons(); // Ensure nav buttons are correctly displayed
        }

        // Event Delegation for options
        optionsListEl.addEventListener('click', (event) => {
            if (event.target && event.target.matches('li.option-item')) {
                // Check if the question has already been answered
                if (userAnswers[currentQuestionIndex] === null) {
                    const selectedIndex = parseInt(event.target.dataset.index, 10);
                    selectOption(selectedIndex);
                }
            }
        });

        prevBtn.addEventListener('click', goToPreviousQuestion);
        nextBtn.addEventListener('click', goToNextQuestion);
        hintBtn.addEventListener('click', showHint);
        
        // 初始加载
        loadQuestion();
      </script>
    </body>
    </html>
  